package com.orange.zk;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

/**
 * Description: zookeeper客户端
 */
public class Client {

    //注意：connectString逗号左右不能有空格，否则连接不上
    private String connectString = "192.168.147.128:2181,192.168.147.129:2181,192.168.147.130:2181";
    //tickTime为2000，initLimit为10
    //LF初次连接时的超时时间应起码大于延迟时间tickTime*initLimit的值否则会因为超时而连接失败。
    private int sessionTimeout = 200000;
    private ZooKeeper zkClient;

    /**
     * 初始化ZooKeeper对象，必须要先创建，再进行创建节点，否则报空指针异常
     *
     * @throws IOException
     */
    @Before
    public void init() throws IOException {
        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //收到时间通知后的回调函数（用户的业务逻辑）
                System.out.println(watchedEvent.getType() + "--" + watchedEvent.getPath());
                //再次启动监听
                try {
                    System.out.println("===============================");
                    //此时监听器使用的客户端上面的哪个匿名内部类watcher
                    List<String> children = zkClient.getChildren("/", true);

                    for (String child : children) {
                        System.out.println(child);
                    }
                    System.out.println("===============================");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Test
    public void create() throws InterruptedException, KeeperException {
        //"/tang"：创建的节点的路径；
        //"t.avi".getBytes():节点里面的值，需要转化为字节传输；
        //ZooDefs.Ids.OPEN_ACL_UNSAFE：权限控制，设置访问权限；
        //CreateMode.PERSISTENT：创建的节点类型，如这个是永久不带序号节点。
        String nodeCreated = zkClient.create("/tang", "t.avi".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }

    /**
     * 监听节点变化信息
     */
    @Test
    public void getChildren() throws KeeperException, InterruptedException {
        System.out.println("-----------------------------");
        //此时监听器使用的客户端上面的哪个匿名内部类watcher
        //参数，1.哪个路径  2.是否开启监听
        List<String> children = zkClient.getChildren("/", true);

        for (String child : children) {
            System.out.println(child);
        }
        System.out.println("-----------------------------");
        //延时阻塞
        Thread.sleep(Long.MAX_VALUE);
    }

    /**
     * 判断节点是否存在
     */
    @Test
    public void exist() throws InterruptedException, KeeperException {
        Stat stat = zkClient.exists("/tang", false);
        System.out.println(stat == null ? "not data" : "exist");
    }
}